package com.dht.xiao.jianye.utils;


import com.dht.xiao.jianye.base.serialport.utils.ByteUtil;
import com.dht.xiao.jianye.base.util.CRC16Utils;
import com.dht.xiao.jianye.command.Protocol;
import com.dht.xiao.jianye.command.base.callback.DataPackCallback;
import com.dht.xiao.jianye.command.base.serialport.DataPack;

import java.nio.ByteBuffer;

/**
 * @author :      fangbingran
 * @aescription : 数据解析
 * @date :        2019/07/29  11:24
 */
public class DiningCabinetHandleDataPack {

   public static boolean handleDataPack(ByteBuffer mByteBuffer, byte[] received, int size, DataPackCallback dataPackCallback) {
        if (mByteBuffer == null) {
            mByteBuffer = ByteBuffer.allocate(1024);
            mByteBuffer.clear();
        }
        try {
            mByteBuffer.put(received, 0, size);
            mByteBuffer.flip();

            byte b;
            int readable;
            byte[] oneBytes = new byte[1];
            byte[] twoBytes = new byte[2];
            // 标记一个第一个元素

            while ((readable = mByteBuffer.remaining()) >= Protocol.MIN_PACK_LEN) {
                mByteBuffer.mark(); // 标记一下开始的位置
                int frameStart = mByteBuffer.position();

                b = mByteBuffer.get();
                if (b != Protocol.FRAME_HEAD_0) { // 第1个byte要AA
                    continue;
                }

                b = mByteBuffer.get();
                if (b != Protocol.FRAME_HEAD_1) { // 第2个byte要66
                    continue;
                }
//
//                // 下一个就是命令长度
                mByteBuffer.position(mByteBuffer.position());

                //AA660311
                //030040A8
                // 数据长度SLEN
                mByteBuffer.get(oneBytes);
                final int slen = (int) ByteUtil.hexStr2decimal(
                        ByteUtil.bytes2HexStr(oneBytes));
//                LogPlus.e("数据长度=" + slen);
                // slen包括command和appdata，所以要把command的1字节减去
                int total = Protocol.MIN_PACK_LEN + slen - 1;
                // 如果可读数据小于总数据长度，表示不够,还有数据没接收
                if (readable < total) {
                    // 重置一下要处理的位置,并跳出循环
                    mByteBuffer.reset();
                    break;
                }
                // 跳过 (COMMAND+APPDATA)=SLEN
                // 找到crc16
                mByteBuffer.position(mByteBuffer.position() + slen);
                mByteBuffer.get(twoBytes);
                String crc16 = ByteUtil.bytes2HexStr(twoBytes).toUpperCase();
                // 回到头
                mByteBuffer.reset();
                // 拿到整个包
                final byte[] data = new byte[total];
                mByteBuffer.get(data);
                String otherCrc16 = CRC16Utils.calcCrc16(ByteUtil.getBytes(data,0,total - 2),  total - 2);

                //  LogPlus.d("crc16=" + crc16 + ",other_crc16=" + otherCrc16);

                if (crc16.equals(otherCrc16)) {
                    // 校验成功
                    byte[] command = ByteUtil.getBytes(data, 3, 1);
                    byte[] appdata = new byte[slen];
                    System.arraycopy(data, 3, appdata, 0, appdata.length);

//                    LogPlus.d("接受到的命令=" + ByteUtil.bytes2HexStr(data));
                    if (dataPackCallback != null) {
                        dataPackCallback.setDataPack(new DataPack(data, appdata, command,true));
                    }

                } else {
                    /**
                     * 异常，出现校验位不一致
                     */
                    byte[] command = ByteUtil.getBytes(data, 3, 1);
                    byte[] appdata = new byte[slen];
                    System.arraycopy(data, 3, appdata, 0, appdata.length);
                    if (dataPackCallback != null) {
                        dataPackCallback.setDataPack(new DataPack(data, appdata, command,false));
                    }
                    // 不一致则回到“第二位”，继续找到下一个3AA3
                    mByteBuffer.position(frameStart + 2);
                }
            }

            // 最后清掉之前处理过的不合适的数据
            mByteBuffer.compact();
        } catch (Exception e) {
            // 最后清掉之前处理过的不合适的数据
            mByteBuffer.compact();
        }

        return true;

    }



}
